﻿using System;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using log4net;
using Microsoft.Build.Evaluation;
using Truncation.Detector.Windows;

namespace Truncation.Detector.Win32
{
    public class Entry : ProjectImpl
    {
        private static readonly ILog Log = LogManager.GetLogger("Main");
        private ISolutionImpl _solution = null;
        private string _currentRc = null;
        private Report _report = new Report();
        private Uri _baseFolder;
        private static Regex LanguagePattern = new Regex(@"^LANGUAGE\s+(\w+),\s+(\w+)$");
        private static Regex DialogPattern = new Regex(@"([A-Za-z0-9_]+)[ \t]+(DIALOGEX|DIALOG)[ \t]*(.*)$");
        private CultureInfo _currentCultureInfo = CultureInfo.InvariantCulture;


        public Entry(Project project) : base(project)
        {
            _baseFolder = new Uri(Environment.CurrentDirectory + Path.DirectorySeparatorChar);
        }

        public override void Run(ISolutionImpl solution)
        {
            Log.InfoFormat("--> Start to parse win32 project: {0}", FullPath);
            this._solution = solution;

            foreach (var page in MsBuildProject.GetItems("ResourceCompile"))
            {
                string include = Path.Combine(MsBuildProject.DirectoryPath, page.EvaluatedInclude);
                Log.DebugFormat("Check rc file: {0}", include);
                Parse(include);
            }
            _report.Output();
        }

        private void Parse(string fileName)
        {
            Summary.Instance.Counts++;
            _currentRc = _baseFolder.MakeRelativeUri(new Uri(fileName)).ToString();
            using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                var encode = FileEncodingDetector.DetectFileEncoding(stream);
                var reader = new PositionReader(stream, encode);
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    line = line.TrimStart(' ');
                    if (String.IsNullOrEmpty(line) || line.StartsWith("//"))
                        continue;
                    Match match = DialogPattern.Match(line);
                    if (match.Success)
                    {
                        using (var dialog = new Dialog(match.Groups[1].Value, match.Groups[3].Value, _currentCultureInfo))
                        {
                            dialog.Read(reader);
                            foreach (var result in dialog.Measure())
                            {
                                _report.Add(_currentRc, result);
                            }
                        }
                        continue;
                    }
                    if (line.StartsWith("LANGUAGE"))
                    {
                        GetCulture(line.Substring("LANGUAGE".Length + 1));
                    }    
                }
                
                reader.Dispose();
            }
        }
        // https://msdn.microsoft.com/en-us/library/windows/desktop/dd318693(v=vs.85).aspx
        private void GetCulture(string segment)
        {
            string[] languages = segment.Replace(" ", String.Empty).Split(',');
            int high = -1;
            int low = -1;
            Int32.TryParse(languages[0], out high);
            Int32.TryParse(languages[1], out low);
            int lcid = LocaleConvert.Get(languages[0], languages[1]);
            _currentCultureInfo = new CultureInfo(lcid);
        }
    }
}
